package com.zhx.threadcoreknowledge.stopthread.volatiledemo;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @author ：zhanghaixuan
 * @date ：Created in 2019-10-01 10:15
 * 用途         ： 无法使用volatile停止线程的情况, 当线程陷入阻塞的时候 volatile是无法停止的
 *
 * 这个例子中, 生产者的生产速度很快, 消费者消费速度慢
 */
public class WrongWatVolatileFixed {

    public static void main(String[] args) throws InterruptedException {
        WrongWatVolatileFixed body = new WrongWatVolatileFixed();

        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(10);

        Producer producer = body.new Producer(arrayBlockingQueue);
        Thread thread = new Thread(producer);
        thread.start();

        Thread.sleep(1500);

        Comsumer comsumer = body.new Comsumer(arrayBlockingQueue);

        while (comsumer.needMoreNums()){
            System.out.println(comsumer.storage.take()+"被消费了");
            Thread.sleep(100);
        }
        System.out.println("消费者不需要更多数据了");

        thread.interrupt();
    }

    class Producer implements Runnable{
        BlockingQueue strage;

        public Producer(BlockingQueue strage) {
            this.strage = strage;
        }

        @Override
        public void run() {
            int num = 0;
            try {
                while (num <= 1000000 && !Thread.currentThread().isInterrupted()) {
                    if (num % 100 == 0) {
                        strage.put(num);
                        System.out.println(num + "是100的倍数");
                    }
                    num ++;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println("生产者停止运行");
            }
        }
    }

    class  Comsumer{
        BlockingQueue storage;

        public Comsumer(BlockingQueue storage) {
            this.storage = storage;
        }

        public boolean needMoreNums(){
            if (Math.random()>0.95) {
                return false;
            }
            return true;
        }
    }
}



